home *** CD-ROM | disk | FTP | other *** search
- Subject: v09i058: Terminal emulator for X window system, Part05/07
- Newsgroups: mod.sources
- Approved: rs@mirror.TMC.COM
-
- Submitted by: edmoy%opal.Berkeley.EDU@berkeley.edu
- Mod.sources: Volume 9, Issue 58
- Archive-name: xterm6.6b/Part05
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # main.c menu.c
- if test -f main.c
- then
- echo shar: will not overwrite existing file "'main.c'"
- else
- echo 'x - main.c'
- cat << \RAZZLE!DAZZLE > main.c
- /*
- * $Source: /u1/X/xterm/RCS/main.c,v $
- * $Header: main.c,v 10.101 86/12/01 16:58:10 swick Rel $
- */
-
- #include <X/mit-copyright.h>
-
- /* Copyright Massachusetts Institute of Technology 1984, 1985 */
-
- /* main.c */
-
- #ifndef lint
- static char sccs_id[] = "@(#)main.c\tX10/6.6B\t12/28/86";
- #endif lint
-
- #include <pwd.h>
- #include <sgtty.h>
- #include <sys/wait.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- #include <stdio.h>
- #include <sys/file.h>
- #include <errno.h>
- #include <signal.h>
- #include <strings.h>
- #include <setjmp.h>
- #include <utmp.h>
- #include <sys/param.h> /* for NOFILE */
- #include <X/Xlib.h>
- #include "scrollbar.h"
- #include "ptyx.h"
- #include "data.h"
- #include "error.h"
- #include "main.h"
-
- int switchfb[] = {0, 2, 1, 3};
-
- static int reapchild ();
-
- static char *brdr_color;
- static char **command_to_exec;
- #ifdef TIOCCONS
- static int Console;
- #endif TIOCCONS
- static struct sgttyb d_sg = {
- 0, 0, 0177, CKILL, EVENP|ODDP|ECHO|XTABS|CRMOD
- };
- static struct tchars d_tc = {
- CINTR, CQUIT, CSTART,
- CSTOP, CEOF, CBRK,
- };
- static struct ltchars d_ltc = {
- CSUSP, CDSUSP, CRPRNT,
- CFLUSH, CWERASE, CLNEXT
- };
- static int d_disipline = NTTYDISC;
- static int d_lmode = LCRTBS|LCRTERA|LCRTKIL|LCTLECH;
- static char def_bold_font[] = DEFBOLDFONT;
- static char def_font[] = DEFFONT;
- static char def_title_font[] = DEFTITLEFONT;
- static char def_icon_font[] = DEFICONFONT;
- static char display[256];
- static char etc_utmp[] = "/etc/utmp";
- static char *get_ty;
- static char *iconbitmap;
- static int inhibit;
- static int log_on;
- static int login_shell;
- static char passedPty[2]; /* name if pty if slave */
- static int loginpty;
- static char *tekiconbitmap;
- static int tslot;
- static char *xdef[] = {
- "ActiveIcon", /* DEF_ACTIVEICON */
- "AllowIconInput", /* DEF_ALLOWICONINPUT */
- "AutoRaise", /* DEF_AUTORAISE */
- "Background", /* DEF_BACKGROUND */
- "BodyFont", /* DEF_BODYFONT */
- "BoldFont", /* DEF_BOLDFONT */
- "Border", /* DEF_BORDER */
- "BorderWidth", /* DEF_BORDERWIDTH */
- "C132", /* DEF_C132 */
- "Curses", /* DEF_CURSES */
- "Cursor", /* DEF_CURSOR */
- "DeiconifyWarp", /* DEF_DEICONWARP */
- "Foreground", /* DEF_FOREGROUND */
- "IconBitmap", /* DEF_ICONBITMAP */
- "IconFont", /* DEF_ICONFONT */
- "IconStartup", /* DEF_ICONSTARTUP */
- "InternalBorder", /* DEF_INTERNALBORDER */
- "JumpScroll", /* DEF_JUMPSCROLL */
- #ifdef KEYBD
- "KeyBoard", /* DEF_KEYBOARD */
- #endif KEYBD
- "LogFile", /* DEF_LOGFILE */
- "Logging", /* DEF_LOGGING */
- "LogInhibit", /* DEF_LOGINHIBIT */
- "LoginShell", /* DEF_LOGINSHELL */
- "MarginBell", /* DEF_MARGINBELL */
- "Mouse", /* DEF_MOUSE */
- "NMarginBell", /* DEF_NMARGINBELL */
- "PageOverlap", /* DEF_PAGEOVERLAP */
- "PageScroll", /* DEF_PAGESCROLL */
- "ReverseVideo", /* DEF_REVERSEVIDEO */
- "ReverseWrap", /* DEF_REVERSEWRAP */
- "SaveLines", /* DEF_SAVELINES */
- "ScrollBar", /* DEF_SCROLLBAR */
- "ScrollInput", /* DEF_SCROLLINPUT */
- "ScrollKey", /* DEF_SCROLLKEY */
- "SignalInhibit", /* DEF_SIGNALINHIBIT */
- "StatusLine", /* DEF_STATUSLINE */
- "StatusNormal", /* DEF_STATUSNORMAL */
- "TekIconBitmap", /* DEF_TEKICONBITMAP */
- "TekInhibit", /* DEF_TEKINHIBIT */
- "TextUnderIcon", /* DEF_TEXTUNDERICON */
- "TitleBar", /* DEF_TITLEBAR */
- "TitleFont", /* DEF_TITLEFONT */
- "VisualBell", /* DEF_VISUALBELL */
- 0,
- };
- #ifdef UTMP
- static int added_utmp_entry;
- #endif UTMP
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- register Screen *screen = &term.screen;
- register char *strind;
- register int i, pty;
- register char **cp;
- short fnflag = 0; /* True iff -fn option used */
- short fbflag = 0; /* True iff -fb option used */
- int Xsocket, mode;
- extern onalarm();
- char *malloc();
- char *basename();
- int xerror(), xioerror();
- #ifdef KEYBD
- extern char *keyboardtype; /* used in XKeyBind.c */
- char *getenv();
- #endif KEYBD
-
- xterm_name = (strcmp(*argv, "-") == 0) ? "xterm" : basename(*argv);
-
- term.flags = WRAPAROUND | SMOOTHSCROLL | AUTOREPEAT;
- screen->border = DEFBORDER;
- screen->borderwidth = DEFBORDERWIDTH;
- screen->reversestatus = TRUE;
- screen->mappedVwin = &screen->fullVwin;
- screen->mappedTwin = &screen->fullTwin;
- f_b = def_bold_font;
- f_n = def_font;
- f_t = def_title_font;
- f_i = def_icon_font;
-
- display[0] = '\0';
- #ifdef KEYBD
- if((strind = getenv("KEYBD")) && *strind) {
- if((keyboardtype = malloc(strlen(strind) + 1)) == NULL)
- SysError(ERROR_KMALLOC);
- strcpy(keyboardtype, strind);
- }
- #endif KEYBD
-
- /*
- * go get options out of default file
- */
- for(i = 0, cp = xdef ; *cp ; i++, cp++) {
- if(!(strind = XGetDefault(xterm_name, *cp)))
- continue;
- switch(i) {
- case DEF_ACTIVEICON:
- if (strcmp (strind, "on") == 0)
- screen->active_icon = TRUE;
- continue;
- case DEF_ALLOWICONINPUT:
- if (strcmp (strind, "on") == 0)
- term.flags |= ICONINPUT;
- continue;
- case DEF_AUTORAISE:
- if (strcmp (strind, "on") == 0)
- screen->autoraise = TRUE;
- continue;
- case DEF_BACKGROUND:
- back_color = strind;
- continue;
- case DEF_BODYFONT:
- f_n = strind;
- fnflag = TRUE;
- continue;
- case DEF_BOLDFONT:
- f_b = strind;
- fbflag = TRUE;
- continue;
- case DEF_BORDER:
- brdr_color = strind;
- continue;
- case DEF_BORDERWIDTH:
- screen->borderwidth = atoi (strind);
- continue;
- case DEF_C132:
- if (strcmp (strind, "on") == 0)
- screen->c132 = TRUE;
- continue;
- case DEF_CURSES:
- if (strcmp (strind, "on") == 0)
- screen->curses = TRUE;
- continue;
- case DEF_CURSOR:
- curs_color = strind;
- continue;
- case DEF_DEICONWARP:
- if (strcmp (strind, "on") == 0)
- screen->deiconwarp = TRUE;
- continue;
- case DEF_FOREGROUND:
- fore_color = strind;
- continue;
- case DEF_ICONBITMAP:
- iconbitmap = strind;
- continue;
- case DEF_ICONFONT:
- f_i = strind;
- continue;
- case DEF_ICONSTARTUP:
- if (strcmp (strind, "on") == 0)
- screen->icon_show = -1;
- continue;
- case DEF_INTERNALBORDER:
- screen->border = atoi (strind);
- continue;
- case DEF_JUMPSCROLL:
- if (strcmp (strind, "on") == 0) {
- screen->jumpscroll = TRUE;
- term.flags &= ~SMOOTHSCROLL;
- }
- continue;
- #ifdef KEYBD
- case DEF_KEYBOARD:
- if(keyboardtype)
- free(keyboardtype);
- keyboardtype = strind;
- continue;
- #endif KEYBD
- case DEF_LOGFILE:
- if(screen->logfile = malloc(strlen(strind) + 1))
- strcpy(screen->logfile, strind);
- continue;
- case DEF_LOGGING:
- if (strcmp (strind, "on") == 0)
- log_on = TRUE;
- continue;
- case DEF_LOGINHIBIT:
- if (strcmp (strind, "on") == 0)
- inhibit |= I_LOG;
- continue;
- case DEF_LOGINSHELL:
- if (strcmp (strind, "on") == 0)
- login_shell = TRUE;
- continue;
- case DEF_MARGINBELL:
- if (strcmp (strind, "on") == 0)
- screen->marginbell = TRUE;
- continue;
- case DEF_MOUSE:
- mous_color = strind;
- continue;
- case DEF_NMARGINBELL:
- n_marginbell = atoi (strind);
- continue;
- case DEF_PAGEOVERLAP:
- if((screen->pageoverlap = atoi (strind) - 1) < 0)
- screen->pageoverlap = -1;
- continue;
- case DEF_PAGESCROLL:
- if (strcmp (strind, "on") == 0)
- screen->pagemode = TRUE;
- continue;
- case DEF_REVERSEVIDEO:
- if (strcmp (strind, "on") == 0)
- re_verse = TRUE;
- continue;
- case DEF_REVERSEWRAP:
- if (strcmp (strind, "on") == 0)
- term.flags |= REVERSEWRAP;
- continue;
- case DEF_SAVELINES:
- save_lines = atoi (strind);
- continue;
- case DEF_SCROLLBAR:
- if (strcmp (strind, "on") == 0)
- screen->scrollbar = SCROLLBARWIDTH;
- continue;
- case DEF_SCROLLINPUT:
- if (strcmp (strind, "on") == 0)
- screen->scrollinput = TRUE;
- continue;
- case DEF_SCROLLKEY:
- if (strcmp (strind, "on") == 0)
- screen->scrollkey = TRUE;
- continue;
- case DEF_SIGNALINHIBIT:
- if (strcmp (strind, "on") == 0)
- inhibit |= I_SIGNAL;
- continue;
- case DEF_STATUSLINE:
- if (strcmp (strind, "on") == 0)
- screen->statusline = TRUE;
- continue;
- case DEF_STATUSNORMAL:
- screen->reversestatus = (strcmp (strind, "on") != 0);
- continue;
- case DEF_TEKICONBITMAP:
- tekiconbitmap = strind;
- continue;
- case DEF_TEKINHIBIT:
- if (strcmp (strind, "on") == 0)
- inhibit |= I_TEK;
- continue;
- case DEF_TEXTUNDERICON:
- if (strcmp (strind, "on") == 0)
- screen->textundericon = TRUE;
- continue;
- case DEF_TITLEBAR:
- if (strcmp (strind, "on") == 0)
- screen->fullVwin.titlebar = TRUE;
- continue;
- case DEF_TITLEFONT:
- f_t = strind;
- continue;
- case DEF_VISUALBELL:
- if (strcmp (strind, "on") == 0)
- screen->visualbell = TRUE;
- continue;
- }
- }
-
- /* parse command line */
-
- for (argc--, argv++ ; argc > 0 ; argc--, argv++) {
- if (**argv == '=') {
- geo_metry = *argv;
- continue;
- }
-
- if (**argv == '%') {
- T_geometry = *argv;
- *T_geometry = '=';
- continue;
- }
-
- if (**argv == '#') {
- icon_geom = *argv;
- *icon_geom = '=';
- continue;
- }
-
- if((strind = index (*argv, ':')) != NULL) {
- strncpy(display, *argv, sizeof(display));
- continue;
- }
-
- if(!(i = (**argv == '-')) && **argv != '+') Syntax ();
-
- switch(argument(&(*argv)[1])) {
- case ARG_132:
- screen->c132 = i;
- continue;
- #ifdef TIOCCONS
- case ARG__C:
- Console = i;
- continue;
- #endif TIOCCONS
- case ARG__L:
- {
- char tt[32];
-
- L_flag = 1;
- get_ty = argv[--argc];
- strcpy(tt,"/dev/");
- strcat(tt, get_ty);
- tt[5] = 'p';
- loginpty = open( tt, O_RDWR, 0 );
- dup2( loginpty, 4 );
- close( loginpty );
- loginpty = 4;
- tt[5] = 't';
- chown(tt, 0, 0);
- chmod(tt, 0622);
- if (open(tt, O_RDWR) < 0) {
- consolepr("open failed\n");
- }
- signal(SIGHUP, SIG_IGN);
- vhangup();
- setpgrp(0,0);
- signal(SIGHUP, SIG_DFL);
- (void) close(0);
- open(tt, O_RDWR, 0);
- dup2(0, 1);
- dup2(0, 2);
- continue;
- }
- case ARG__S:
- if(i) {
- if (--argc <= 0) Syntax ();
- sscanf(*++argv, "%c%c%d", passedPty, passedPty+1,
- &am_slave);
- if (am_slave <= 0) Syntax();
- } else
- am_slave = 0;
- continue;
- case ARG_AI:
- screen->active_icon = i;
- continue;
- case ARG_AR:
- screen->autoraise = i;
- continue;
- case ARG_B:
- if(i) {
- if (--argc <= 0) Syntax ();
- screen->border = atoi (*++argv);
- } else
- screen->border = DEFBORDER;
- continue;
- case ARG_BD:
- if(i) {
- if (--argc <= 0) Syntax ();
- brdr_color = *++argv;
- } else
- brdr_color = NULL;
- continue;
- case ARG_BG:
- if(i) {
- if (--argc <= 0) Syntax ();
- back_color = *++argv;
- } else
- back_color = NULL;
- continue;
- case ARG_BW:
- if(i) {
- if (--argc <= 0) Syntax ();
- screen->borderwidth = atoi (*++argv);
- } else
- screen->borderwidth = DEFBORDERWIDTH;
- continue;
- case ARG_CR:
- if(i) {
- if (--argc <= 0) Syntax ();
- curs_color = *++argv;
- } else
- curs_color = NULL;
- continue;
- case ARG_CU:
- screen->curses = i;
- continue;
- #ifdef DEBUG
- case ARG_D:
- debug = i;
- continue;
- #endif DEBUG
- case ARG_DW:
- screen->deiconwarp = i;
- continue;
- case ARG_E:
- if(!i) Syntax();
- if (argc <= 1) Syntax ();
- command_to_exec = ++argv;
- break;
- case ARG_FB:
- if(fbflag = i) {
- if (--argc <= 0) Syntax ();
- f_b = *++argv;
- fbflag = TRUE;
- } else {
- f_b = def_bold_font;
- fbflag = FALSE;
- }
- continue;
- case ARG_FG:
- if(i) {
- if (--argc <= 0) Syntax ();
- fore_color = *++argv;
- } else
- fore_color = NULL;
- continue;
- case ARG_FI:
- if (i) {
- if (--argc <= 0) Syntax();
- f_i = *++argv;
- } else
- f_i = def_icon_font;
- continue;
- case ARG_FN:
- if(fnflag = i) {
- if (--argc <= 0) Syntax ();
- f_n = *++argv;
- fnflag = TRUE;
- } else {
- f_n = def_font;
- fnflag = FALSE;
- }
- continue;
- case ARG_FT:
- if(i) {
- if (--argc <= 0) Syntax ();
- f_t = *++argv;
- } else
- f_t = def_title_font;
- continue;
- case ARG_I:
- screen->icon_show = i ? -1 : 0;
- continue;
- case ARG_IB:
- if(i) {
- if (--argc <= 0) Syntax ();
- iconbitmap = *++argv;
- } else
- iconbitmap = NULL;
- continue;
- case ARG_IT:
- if(i) {
- if (--argc <= 0) Syntax ();
- tekiconbitmap = *++argv;
- } else
- tekiconbitmap = NULL;
- continue;
- case ARG_J:
- if(screen->jumpscroll = i)
- term.flags &= ~SMOOTHSCROLL;
- else
- term.flags |= SMOOTHSCROLL;
- continue;
- #ifdef KEYBD
- case ARG_K:
- if(i) {
- if (--argc <= 0) Syntax ();
- keyboardtype = *++argv;
- } else
- keyboardtype = NULL;
- continue;
- #endif KEYBD
- case ARG_L:
- log_on = i;
- continue;
- case ARG_LF:
- if(screen->logfile)
- free(screen->logfile);
- if(i) {
- if (--argc <= 0) Syntax ();
- if(screen->logfile = malloc(strlen(*++argv) + 1))
- strcpy(screen->logfile, *argv);
- } else
- screen->logfile = NULL;
- continue;
- case ARG_LS:
- login_shell = i;
- continue;
- case ARG_MB:
- screen->marginbell = i;
- continue;
- case ARG_MS:
- if(i) {
- if (--argc <= 0) Syntax ();
- mous_color = *++argv;
- } else
- mous_color = NULL;
- continue;
- case ARG_N:
- if(i) {
- if (--argc <= 0) Syntax ();
- win_name = *++argv;
- } else
- win_name = NULL;
- continue;
- case ARG_NB:
- if(i) {
- if (--argc <= 0) Syntax ();
- n_marginbell = atoi (*++argv);
- } else
- n_marginbell = N_MARGINBELL;
- continue;
- case ARG_PO:
- if(i) {
- if (--argc <= 0) Syntax ();
- if((screen->pageoverlap = atoi (*++argv) - 1) < 0)
- screen->pageoverlap = -1;
- } else
- screen->pageoverlap = 0;
- continue;
- case ARG_PS:
- screen->pagemode = i;
- continue;
- case ARG_RV:
- re_verse = i;
- continue;
- case ARG_RW:
- if(i)
- term.flags |= REVERSEWRAP;
- else
- term.flags &= ~REVERSEWRAP;
- continue;
- case ARG_S:
- screen->multiscroll = i;
- continue;
- case ARG_SB:
- screen->scrollbar = i ? SCROLLBARWIDTH : 0;
- continue;
- case ARG_SI:
- screen->scrollinput = i;
- continue;
- case ARG_SK:
- screen->scrollkey = i;
- continue;
- case ARG_SL:
- if(i) {
- if (--argc <= 0) Syntax ();
- save_lines = atoi (*++argv);
- } else
- save_lines = SAVELINES;
- continue;
- case ARG_SN:
- screen->reversestatus = !i;
- continue;
- case ARG_ST:
- screen->statusline = i;
- continue;
- case ARG_T:
- screen->TekEmu = i;
- continue;
- case ARG_TB:
- screen->fullVwin.titlebar = i;
- continue;
- case ARG_TI:
- screen->textundericon = i;
- continue;
- case ARG_VB:
- screen->visualbell = i;
- continue;
- default:
- Syntax ();
- }
- break;
- }
-
- term.initflags = term.flags;
-
- if (fnflag && !fbflag) f_b = NULL;
- if (!fnflag && fbflag) f_n = f_b;
- if(!win_name) {
- if(get_ty) {
- char b[256];
-
- gethostname(b, sizeof(b) - 1);
- b[sizeof(b) - 1] = 0;
- if(strind = index(b, '.')) /* remove domain */
- *strind = 0;
- win_name = malloc(strlen(b) + 8);
- strcpy(win_name, "login(");
- strcat(win_name, b);
- strcat(win_name, ")");
- } else
- win_name = (am_slave ? "xterm slave" :
- (command_to_exec ? basename(command_to_exec[0]) :
- xterm_name));
- }
- if(inhibit & I_TEK)
- screen->TekEmu = FALSE;
-
- /* set up stderr properly */
- i = -1;
- #ifdef DEBUG
- if(debug)
- i = open ("xterm.debug.log", O_WRONLY | O_CREAT | O_TRUNC,
- 0666);
- else
- #endif DEBUG
- if(get_ty)
- i = open("/dev/console", O_WRONLY);
- if(i >= 0)
- fileno(stderr) = i;
- if(fileno(stderr) != (NOFILE - 1)) {
- dup2(fileno(stderr), (NOFILE - 1));
- if(fileno(stderr) >= 3)
- close(fileno(stderr));
- fileno(stderr) = (NOFILE - 1);
- }
-
- signal (SIGCHLD, reapchild);
- signal (SIGHUP, SIG_IGN);
- signal(SIGALRM, onalarm);
-
- /* open a terminal for client */
- get_terminal ();
- spawn ();
-
- Xsocket = screen->display->fd;
- pty = screen->respond;
-
- if (am_slave) { /* Write window id so master end can read and use */
- write(pty, screen->TekEmu ? (char *)&TWindow(screen) :
- (char *)&VWindow(screen), sizeof(Window));
- write(pty, "\n", 1);
- }
-
- if(log_on) {
- log_on = FALSE;
- StartLog(screen);
- }
- screen->inhibit = inhibit;
- mode = 1;
- if (ioctl (pty, FIONBIO, &mode) == -1) SysError (ERROR_FIONBIO);
-
- pty_mask = 1 << pty;
- X_mask = 1 << Xsocket;
- Select_mask = pty_mask | X_mask;
- max_plus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty);
-
- #ifdef DEBUG
- if (debug) printf ("debugging on\n");
- #endif DEBUG
- XErrorHandler(xerror);
- XIOErrorHandler(xioerror);
- for( ; ; )
- if(screen->TekEmu)
- TekRun();
- else
- VTRun();
- }
-
- char *basename(name)
- char *name;
- {
- register char *cp;
- char *rindex();
-
- return((cp = rindex(name, '/')) ? cp + 1 : name);
- }
-
- static struct argstr {
- char *arg;
- int val;
- } arg[] = {
- {"132", ARG_132},
- #ifdef TIOCCONS
- {"C", ARG__C},
- #endif TIOCCONS
- {"L", ARG__L},
- {"S", ARG__S},
- {"ai", ARG_AI},
- {"ar", ARG_AR},
- {"b", ARG_B},
- {"bd", ARG_BD},
- {"bg", ARG_BG},
- {"bw", ARG_BW},
- {"cr", ARG_CR},
- {"cu", ARG_CU},
- #ifdef DEBUG
- {"d", ARG_D},
- #endif DEBUG
- {"dw", ARG_DW},
- {"e", ARG_E},
- {"fb", ARG_FB},
- {"fg", ARG_FG},
- {"fi", ARG_FI},
- {"fn", ARG_FN},
- {"ft", ARG_FT},
- {"i", ARG_I},
- {"ib", ARG_IB},
- {"it", ARG_IT},
- {"j", ARG_J},
- #ifdef KEYBD
- {"k", ARG_K},
- #endif KEYBD
- {"l", ARG_L},
- {"lf", ARG_LF},
- {"ls", ARG_LS},
- {"mb", ARG_MB},
- {"ms", ARG_MS},
- {"n", ARG_N},
- {"nb", ARG_NB},
- {"po", ARG_PO},
- {"ps", ARG_PS},
- {"r", ARG_RV},
- {"rv", ARG_RV},
- {"rw", ARG_RW},
- {"s", ARG_S},
- {"sb", ARG_SB},
- {"si", ARG_SI},
- {"sk", ARG_SK},
- {"sl", ARG_SL},
- {"sn", ARG_SN},
- {"st", ARG_ST},
- {"t", ARG_T},
- {"tb", ARG_TB},
- {"ti", ARG_TI},
- {"vb", ARG_VB},
- {"w", ARG_BW},
- };
-
- argument(s)
- register char *s;
- {
- register int i, low, high, com;
-
- low = 0;
- high = sizeof(arg) / sizeof(struct argstr) - 1;
- while(low <= high) {/* use binary search, arg in lexigraphic order */
- i = (low + high) / 2;
- if ((com = strcmp(s, arg[i].arg)) == 0)
- return(arg[i].val);
- if(com > 0)
- low = i + 1;
- else
- high = i - 1;
- }
- return(-1);
- }
-
- static char *ustring[] = {
- "Usage: xterm [-132] [-ai] [-ar] [-b margin_width] [-bd border_color] \\\n",
- #ifdef ARG__C
- " [-bg backgrnd_color] [-bw border_width] [-C] [-cr cursor_color] [-cu] \\\n",
- #else ARG__C
- " [-bg backgrnd_color] [-bw border_width] [-cr cursor_color] [-cu] \\\n",
- #endif ARG__C
- " [-dw] [-fb bold_font] [-fg foregrnd_color] [-fi icon_font] [-fn norm_font] \\\n",
- " [-ft title_font] [-i] [-ib iconbitmap] [-it tekiconbitmap] [-j] \\\n",
- #ifdef ARG_K
- " [-k keybd] [-l] [-lf logfile] [-ls] [-mb] [-ms mouse_color] \\\n",
- #else ARG_K
- " [-l] [-lf logfile] [-ls] [-mb] [-ms mouse_color] \\\n",
- #endif ARG_K
- " [-n name] [-nb bell_margin] [-po] [-ps] [-rv] [-rw] [-s] \\\n",
- " [-sb] [-si] [-sk] [-sl save_lines] [-sn] [-st] [-t] [-tb] \\\n",
- " [-ti] [-vb] [=[width]x[height][[+-]xoff[[+-]yoff]]] \\\n",
- " [%[width]x[height][[+-]xoff[[+-]yoff]]] [#[+-]xoff[[+-]yoff]] \\\n",
- " [-e command_to_exec]\n\n",
- "Fonts must be of fixed width and of same size;\n",
- "If only one font is specified, it will be used for normal and bold text\n",
- "The -132 option allows 80 <-> 132 column escape sequences\n",
- "The -ai option turns on miniature (active) icons\n",
- "The -ar option turns auto raise window mode on\n",
- #ifdef ARG__C
- "The -C option forces output to /dev/console to appear in this window\n",
- #endif ARG__C
- "The -cu option turns a curses bug fix on\n",
- "The -dw option warps the mouse on deiconify\n",
- "The -i option enables icon startup\n",
- "The -j option enables jump scroll\n",
- "The -l option enables logging\n",
- "The -ls option makes the shell a login shell\n",
- "The -mb option turns the margin bell on\n",
- "The -ps option turns page scroll on\n",
- "The -rv option turns reverse video on\n",
- "The -rw option turns reverse wraparound on\n",
- "The -s option enables asynchronous scrolling\n",
- "The -sb option enables the scrollbar\n",
- "The -si option enables re-positioning the scrollbar at the bottom on input\n",
- "The -sk option causes the scrollbar to position at the bottom on a key\n",
- "The -sn option makes the status line normal video \n",
- "The -st option enables the status line\n",
- "The -t option starts Tektronix mode\n",
- "The -tb option enables the titlebar\n",
- "The -ti option places the window name under the icon\n",
- "The -vb option enables visual bell\n",
- 0
- };
-
- Syntax ()
- {
- register char **us = ustring;
-
- while (*us) fputs(*us++, stderr);
- exit (1);
- }
-
- get_pty (pty, tty)
- /*
- opens a pty, storing fildes in pty and tty.
- */
- int *pty, *tty;
- {
- int devindex, letter = 0;
-
- while (letter < 4) {
- ttydev [8] = ptydev [8] = "pqrs" [letter++];
- devindex = 0;
-
- while (devindex < 16) {
- ttydev [9] = ptydev [9] = "0123456789abcdef" [devindex++];
- if ((*pty = open (ptydev, O_RDWR)) < 0)
- continue;
- if ((*tty = open (ttydev, O_RDWR)) < 0) {
- close(*pty);
- continue;
- }
- return;
- }
- }
-
- fprintf (stderr, "%s: Not enough available pty's\n", xterm_name);
- exit (ERROR_PTYS);
- }
-
- get_terminal ()
- /*
- * sets up X and initializes the terminal structure except for term.buf.fildes.
- */
- {
- register Screen *screen = &term.screen;
- register int try;
- Color cdef;
- char *malloc();
-
- for (try = 10 ; ; ) {
- if (screen->display = XOpenDisplay(display))
- break;
- if (!get_ty) {
- fprintf(stderr, "%s: No such display server %s\n", xterm_name,
- XDisplayName(display));
- exit(ERROR_NOX);
- }
- if (--try <= 0) {
- fprintf (stderr, "%s: Can't connect to display server %s\n",
- xterm_name, XDisplayName(display));
- exit (ERROR_NOX2);
- }
- sleep (5);
- }
-
- if(re_verse) {
- B_Pixel = WhitePixel;
- B_Pixmap = WhitePixmap;
- W_Pixel = BlackPixel;
- W_Pixmap = BlackPixmap;
- } else {
- B_Pixel = BlackPixel;
- B_Pixmap = BlackPixmap;
- W_Pixel = WhitePixel;
- W_Pixmap = WhitePixmap;
- }
-
- if (brdr_color && DisplayCells() > 2 &&
- XParseColor(brdr_color, &cdef) && XGetHardwareColor(&cdef)) {
- if(!(screen->bordertile = XMakeTile(cdef.pixel)))
- Error(ERROR_BORDER);
- } else
- screen->bordertile = B_Pixmap;
- screen->graybordertile = make_gray();
-
- screen->foreground = B_Pixel;
- screen->background = W_Pixel;
- screen->cursorcolor = B_Pixel;
- screen->mousecolor = B_Pixel;
-
- if (DisplayCells() > 2 && (fore_color || back_color ||
- curs_color)) {
- if (fore_color && XParseColor(fore_color, &cdef) &&
- XGetHardwareColor(&cdef)) {
- screen->foreground = cdef.pixel;
- screen->color |= C_FOREGROUND;
- }
- if (back_color && XParseColor(back_color, &cdef) &&
- XGetHardwareColor(&cdef)) {
- screen->background = cdef.pixel;
- screen->color |= C_BACKGROUND;
- }
- if (curs_color && XParseColor(curs_color, &cdef) &&
- XGetHardwareColor(&cdef)) {
- screen->cursorcolor = cdef.pixel;
- screen->color |= C_CURSOR;
- } else
- screen->cursorcolor = screen->foreground;
- }
-
- if (mous_color && DisplayCells() > 2 &&
- XParseColor(mous_color, &cdef) && XGetHardwareColor(&cdef)) {
- screen->mousecolor = cdef.pixel;
- screen->color |= C_MOUSE;
- } else
- screen->mousecolor = screen->cursorcolor;
-
- if(screen->color & C_BACKGROUND) {
- if(!(screen->bgndtile = XMakeTile(screen->background)))
- Error(ERROR_BACK);
- } else
- screen->bgndtile = W_Pixmap;
- screen->arrow = make_arrow(screen->mousecolor, screen->background,
- GXcopy);
-
- XAutoRepeatOn();
- if((screen->titlefont = XOpenFont(f_t)) == NULL) {
- fprintf(stderr, "%s: Can't get title font %s\n", xterm_name,
- f_t);
- exit(ERROR_TITLEFONT);
- }
- screen->title_n_size= XQueryWidth("m", screen->titlefont->id);
- screen->titleheight = screen->titlefont->height + 2 * TITLEPAD + 1;
- if(screen->fullVwin.titlebar)
- screen->fullVwin.titlebar =
- screen->fullTwin.titlebar = screen->titleheight;
- IconInit(screen, iconbitmap, tekiconbitmap);
- }
-
- static char *tekterm[] = {
- "tek4015",
- "tek4014",
- "tek4013",
- "tek4010",
- "dumb",
- 0
- };
-
- static char *vtterm[] = {
- "xterms",
- "xterm",
- "vt102",
- "vt100",
- "ansi",
- "dumb",
- 0
- };
-
- spawn ()
- /*
- * Inits pty and tty and forks a login process.
- * Does not close fd Xsocket.
- * If getty, execs getty rather than csh and uses std fd's rather
- * than opening a pty/tty pair.
- * If slave, the pty named in passedPty is already open for use
- */
- {
- register Screen *screen = &term.screen;
- int Xsocket = screen->display->fd;
- int index1, tty = -1;
- int discipline;
- unsigned lmode;
- struct tchars tc;
- struct ltchars ltc;
- struct sgttyb sg;
-
- char termcap [1024];
- char newtc [1024];
- char *ptr, *shname;
- int i, no_dev_tty = FALSE;
- char **envnew; /* new environment */
- char buf[32];
- char *TermName = NULL;
- int ldisc = 0;
- #ifdef sun
- #ifdef TIOCSSIZE
- struct ttysize ts;
- #endif TIOCSSIZE
- #else sun
- #ifdef TIOCSWINSZ
- struct winsize ws;
- #endif TIOCSWINSZ
- #endif sun
- struct passwd *pw = NULL;
- #ifdef UTMP
- struct utmp utmp;
- #endif UTMP
- extern int Exit();
- struct passwd *getpwuid();
- char *getenv();
- char *index (), *rindex (), *strindex ();
-
- screen->uid = getuid();
- screen->gid = getgid();
-
- #ifdef UTMP
- added_utmp_entry = FALSE;
- #endif UTMP
- /* so that TIOCSWINSZ || TIOCSIZE doesn't block */
- signal(SIGTTOU,SIG_IGN);
- if(!(screen->TekEmu ? TekInit() : VTInit()))
- exit(ERROR_INIT);
-
- if(screen->TekEmu) {
- envnew = tekterm;
- ptr = newtc;
- } else {
- /*
- * Special case of a 80x24 window, use "xterms"
- */
- envnew = (screen->max_col == 79 && screen->max_row ==
- 23) ? vtterm : &vtterm[1];
- ptr = termcap;
- }
- while(*envnew) {
- if(tgetent(ptr, *envnew) == 1) {
- TermName = *envnew;
- if(!screen->TekEmu)
- resize(screen, TermName, termcap, newtc);
- break;
- }
- envnew++;
- }
-
- if (get_ty) {
- screen->respond = loginpty;
- if((tslot = ttyslot()) <= 0)
- SysError(ERROR_TSLOT);
- #ifdef TIOCCONS
- if (Console) {
- int on = 1;
- if (ioctl (0, TIOCCONS, &on) == -1)
- SysError(ERROR_TIOCCONS);
- }
- #endif TIOCCONS
- } else if (am_slave) {
- screen->respond = am_slave;
- ptydev[8] = ttydev[8] = passedPty[0];
- ptydev[9] = ttydev[9] = passedPty[1];
- if((tslot = ttyslot()) <= 0)
- SysError(ERROR_TSLOT2);
- setgid (screen->gid);
- setuid (screen->uid);
- } else {
- if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0) {
- if (errno != ENXIO) SysError(ERROR_OPDEVTTY);
- else {
- no_dev_tty = TRUE;
- sg = d_sg;
- tc = d_tc;
- discipline = d_disipline;
- ltc = d_ltc;
- lmode = d_lmode;
- }
- } else {
- /* get a copy of the current terminal's state */
-
- if(ioctl(tty, TIOCGETP, &sg) == -1)
- SysError (ERROR_TIOCGETP);
- if(ioctl(tty, TIOCGETC, &tc) == -1)
- SysError (ERROR_TIOCGETC);
- if(ioctl(tty, TIOCGETD, &discipline) == -1)
- SysError (ERROR_TIOCGETD);
- if(ioctl(tty, TIOCGLTC, <c) == -1)
- SysError (ERROR_TIOCGLTC);
- if(ioctl(tty, TIOCLGET, &lmode) == -1)
- SysError (ERROR_TIOCLGET);
- close (tty);
-
- /* close all std file descriptors */
- for (index1 = 0; index1 < 3; index1++)
- close (index1);
- if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0)
- SysError (ERROR_OPDEVTTY2);
-
- if (ioctl (tty, TIOCNOTTY, 0) == -1)
- SysError (ERROR_NOTTY);
- close (tty);
- }
-
- get_pty (&screen->respond, &tty);
-
- if (screen->respond != Xsocket + 1) {
- dup2 (screen->respond, Xsocket + 1);
- close (screen->respond);
- screen->respond = Xsocket + 1;
- }
-
- /* change ownership of tty to real group and user id */
- chown (ttydev, screen->uid, screen->gid);
-
- /* change protection of tty */
- chmod (ttydev, 0622);
-
- if (tty != Xsocket + 2) {
- dup2 (tty, Xsocket + 2);
- close (tty);
- tty = Xsocket + 2;
- }
-
- /* set the new terminal's state to be the old one's
- with minor modifications for efficiency */
-
- sg.sg_flags &= ~(ALLDELAY | XTABS | CBREAK | RAW);
- sg.sg_flags |= ECHO | CRMOD;
- /* make sure speed is set on pty so that editors work right*/
- sg.sg_ispeed = B9600;
- sg.sg_ospeed = B9600;
- /* reset t_brkc to default value */
- tc.t_brkc = -1;
-
- if (ioctl (tty, TIOCSETP, &sg) == -1)
- SysError (ERROR_TIOCSETP);
- if (ioctl (tty, TIOCSETC, &tc) == -1)
- SysError (ERROR_TIOCSETC);
- if (ioctl (tty, TIOCSETD, &discipline) == -1)
- SysError (ERROR_TIOCSETD);
- if (ioctl (tty, TIOCSLTC, <c) == -1)
- SysError (ERROR_TIOCSLTC);
- if (ioctl (tty, TIOCLSET, &lmode) == -1)
- SysError (ERROR_TIOCLSET);
- #ifdef TIOCCONS
- if (Console) {
- int on = 1;
- if (ioctl (tty, TIOCCONS, &on) == -1)
- SysError(ERROR_TIOCCONS);
- }
- #endif TIOCCONS
-
- close (open ("/dev/null", O_RDWR, 0));
-
- for (index1 = 0; index1 < 3; index1++)
- dup2 (tty, index1);
- if((tslot = ttyslot()) <= 0)
- SysError(ERROR_TSLOT3);
- #ifdef UTMP
- if((pw = getpwuid(screen->uid)) &&
- (i = open(etc_utmp, O_WRONLY)) >= 0) {
- bzero((char *)&utmp, sizeof(struct utmp));
- (void) strcpy(utmp.ut_line, &ttydev[5]);
- (void) strcpy(utmp.ut_name, pw->pw_name);
- (void) strcpy(utmp.ut_host, DisplayName());
- time(&utmp.ut_time);
- lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
- write(i, (char *)&utmp, sizeof(struct utmp));
- close(i);
- added_utmp_entry = TRUE;
- }
- #endif UTMP
- }
-
- #ifdef sun
- #ifdef TIOCSSIZE
- /* tell tty how big window is */
- if(screen->TekEmu) {
- ts.ts_lines = 38;
- ts.ts_cols = 81;
- } else {
- ts.ts_lines = screen->max_row + 1;
- ts.ts_cols = screen->max_col + 1;
- }
- ioctl (screen->respond, TIOCSSIZE, &ts);
- #endif TIOCSSIZE
- #else sun
- #ifdef TIOCSWINSZ
- /* tell tty how big window is */
- if(screen->TekEmu) {
- ws.ws_row = 38;
- ws.ws_col = 81;
- ws.ws_xpixel = TFullWidth(screen);
- ws.ws_ypixel = TFullHeight(screen);
- } else {
- ws.ws_row = screen->max_row + 1;
- ws.ws_col = screen->max_col + 1;
- ws.ws_xpixel = FullWidth(screen);
- ws.ws_ypixel = FullHeight(screen);
- }
- ioctl (screen->respond, TIOCSWINSZ, &ws);
- #endif TIOCSWINSZ
- #endif sun
-
- if (!am_slave) {
- if ((screen->pid = fork ()) == -1)
- SysError (ERROR_FORK);
-
- if (screen->pid == 0) {
- extern char **environ;
- int pgrp = getpid();
- char shell_name[64];
-
- close (Xsocket);
- close (screen->respond);
- if(fileno(stderr) >= 3)
- close (fileno(stderr));
-
- if (tty >= 0) close (tty);
-
- signal (SIGCHLD, SIG_DFL);
- signal (SIGHUP, SIG_IGN);
-
- /* copy the environment before Setenving */
- for (i = 0 ; environ [i] != NULL ; i++) ;
- /*
- * The `4' is the number of Setenv() calls which may add
- * a new entry to the environment. The `1' is for the
- * NULL terminating entry.
- */
- envnew = (char **) calloc (i + (4 + 1), sizeof(char *));
- bcopy((char *)environ, (char *)envnew, i * sizeof(char *));
- environ = envnew;
- Setenv ("TERM=", TermName);
- if(!TermName)
- *newtc = 0;
- Setenv ("TERMCAP=", newtc);
- sprintf(buf, "%d", screen->TekEmu ? (int)TWindow(screen) :
- (int)VWindow(screen));
- Setenv ("WINDOWID=", buf);
- /* put the display into the environment of the shell*/
- if (display[0] != '\0')
- Setenv ("DISPLAY=", screen->display->displayname);
-
- signal(SIGTERM, SIG_DFL);
- ioctl(0, TIOCSPGRP, &pgrp);
- setpgrp (0, 0);
- close(open(ttyname(0), O_WRONLY, 0));
- setpgrp (0, pgrp);
-
- setgid (screen->gid);
- setuid (screen->uid);
-
- if (command_to_exec) {
- execvp(*command_to_exec, command_to_exec);
- /* print error message on screen */
- fprintf(stderr, "%s: Can't execvp %s\n", xterm_name,
- *command_to_exec);
- }
- signal(SIGHUP, SIG_IGN);
- if (get_ty) {
- ioctl (0, TIOCNOTTY, 0);
- execl ("/etc/getty", "+", "Xwindow", get_ty, 0);
- }
- signal(SIGHUP, SIG_DFL);
-
- #ifdef UTMP
- if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
- ((pw == NULL && (pw = getpwuid(screen->uid)) == NULL) ||
- *(ptr = pw->pw_shell) == 0))
- #else UTMP
- if(((ptr = getenv("SHELL")) == NULL || *ptr == 0) &&
- ((pw = getpwuid(screen->uid)) == NULL ||
- *(ptr = pw->pw_shell) == 0))
- #endif UTMP
- ptr = "/bin/sh";
- if(shname = rindex(ptr, '/'))
- shname++;
- else
- shname = ptr;
- i = strlen(shname) - 3;
- ldisc = (strcmp("csh", shname + i) == 0 ||
- strcmp("ksh", shname + i) == 0) ? NTTYDISC : 0;
- ioctl(0, TIOCSETD, &ldisc);
- if(login_shell)
- strcpy(shell_name, "-");
- else
- *shell_name = 0;
- strcat(shell_name, shname);
- execl (ptr, shell_name, 0);
- fprintf (stderr, "%s: Could not exec %s!\n", xterm_name, ptr);
- sleep(5);
- exit(ERROR_EXEC);
- }
- }
-
- if(tty >= 0) close (tty);
- signal(SIGHUP,SIG_IGN);
-
- if (!no_dev_tty) {
- if ((tty = open ("/dev/tty", O_RDWR, 0)) < 0)
- SysError(ERROR_OPDEVTTY3);
- for (index1 = 0; index1 < 3; index1++)
- dup2 (tty, index1);
- if (tty > 2) close (tty);
- }
-
- signal(SIGINT, Exit);
- signal(SIGQUIT, Exit);
- signal(SIGTERM, Exit);
- }
-
- Exit(n)
- int n;
- {
- register Screen *screen = &term.screen;
- #ifdef UTMP
- register int i;
- struct utmp utmp;
-
- if(added_utmp_entry && (i = open(etc_utmp, O_WRONLY)) >= 0) {
- bzero((char *)&utmp, sizeof(struct utmp));
- lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
- write(i, (char *)&utmp, sizeof(struct utmp));
- close(i);
- }
- #endif UTMP
- if(screen->logging)
- CloseLog(screen);
-
- if(!get_ty && !am_slave) {
- /* restore ownership of tty */
- chown (ttydev, 0, 0);
-
- /* restore modes of tty */
- chmod (ttydev, 0666);
- }
- exit(n);
- }
-
- resize(screen, TermName, oldtc, newtc)
- Screen *screen;
- char *TermName;
- register char *oldtc, *newtc;
- {
- register char *ptr1, *ptr2;
- register int i;
- register int li_first = 0;
- register char *temp;
- char *index(), *strindex();
-
- if ((ptr1 = strindex (oldtc, "co#")) == NULL){
- fprintf(stderr, "%s: Can't find co# in termcap string %s\n",
- xterm_name, TermName);
- exit (ERROR_NOCO);
- }
- if ((ptr2 = strindex (oldtc, "li#")) == NULL){
- fprintf(stderr, "%s: Can't find li# in termcap string %s\n",
- xterm_name, TermName);
- exit (ERROR_NOLI);
- }
- if(ptr1 > ptr2) {
- li_first++;
- temp = ptr1;
- ptr1 = ptr2;
- ptr2 = temp;
- }
- ptr1 += 3;
- ptr2 += 3;
- strncpy (newtc, oldtc, i = ptr1 - oldtc);
- newtc += i;
- sprintf (newtc, "%d", li_first ? screen->max_row + 1 :
- screen->max_col + 1);
- newtc += strlen(newtc);
- ptr1 = index (ptr1, ':');
- strncpy (newtc, ptr1, i = ptr2 - ptr1);
- newtc += i;
- sprintf (newtc, "%d", li_first ? screen->max_col + 1 :
- screen->max_row + 1);
- ptr2 = index (ptr2, ':');
- strcat (newtc, ptr2);
- }
-
- static reapchild ()
- {
- union wait status;
- register int pid;
-
- #ifdef DEBUG
- if (debug) fputs ("Exiting\n", stderr);
- #endif DEBUG
- pid = wait3 (&status, WNOHANG, NULL);
- if (!pid) return;
- if (pid != term.screen.pid) return;
-
- Cleanup(0);
- }
-
- consolepr(string)
- char *string;
- {
- extern int errno;
- extern char *sys_errlist[];
- int oerrno;
- int f;
-
- oerrno = errno;
- f = open("/dev/console",O_WRONLY);
- write(f, "xterm: ", 7);
- write(f, string, strlen(string));
- write(f, ": ", 2);
- write(f, sys_errlist[oerrno],strlen(sys_errlist[oerrno]));
- write(f, "\n", 1);
- close(f);
- if ((f = open("/dev/tty", 2)) >= 0) {
- ioctl(f, TIOCNOTTY, 0);
- close(f);
- }
- }
-
- checklogin()
- {
- register int i, j;
- register struct passwd *pw;
- struct utmp utmp;
-
- if((i = open(etc_utmp, O_RDONLY)) < 0)
- return(FALSE);
- lseek(i, (long)(tslot * sizeof(struct utmp)), 0);
- j = read(i, (char *)&utmp, sizeof(utmp));
- close(i);
- if(j != sizeof(utmp) || strcmp(get_ty, utmp.ut_line) != 0 ||
- !*utmp.ut_name || (pw = getpwnam(utmp.ut_name)) == NULL)
- return(FALSE);
- chdir(pw->pw_dir);
- setgid(pw->pw_gid);
- setuid(pw->pw_uid);
- L_flag = 0;
- return(TRUE);
- }
- RAZZLE!DAZZLE
- fi # End main.c
- if test -f menu.c
- then
- echo shar: will not overwrite existing file "'menu.c'"
- else
- echo 'x - menu.c'
- cat << \RAZZLE!DAZZLE > menu.c
- /*
- * $Source: /u1/X/xterm/RCS/menu.c,v $
- * $Header: menu.c,v 10.101 86/12/01 17:52:43 swick Rel $
- */
-
- #ifdef MODEMENU
- #include "X/Xlib.h"
- #include "menu.h"
-
- #ifndef lint
- static char sccs_id[] = "@(#)menu.c\tX10/6.6B\t12/26/86";
- #endif lint
-
- #define FALSE 0
- #define TRUE 1
- #define InvertPlane 1
- #define SetStateFlags(item) item->itemFlags = (item->itemFlags &\
- ~(itemStateMask | itemChanged)) |\
- ((item->itemFlags & itemSetMask) >>\
- itemSetMaskShift)
-
-
- static short Check_MarkBits[] = {
- 0x0100, 0x0180, 0x00c0, 0x0060,
- 0x0031, 0x001b, 0x000e, 0x0004
- };
- static short Check_GrayBits[] = {
- 0x0100, 0x0080, 0x0040, 0x0020,
- 0x0011, 0x000a, 0x0004, 0x0000
- };
- static short Default_CursorBits[] = {
- 0x0000, 0x0002, 0x0006, 0x000e,
- 0x001e, 0x003e, 0x007e, 0x00fe,
- 0x01fe, 0x003e, 0x0036, 0x0062,
- 0x0060, 0x00c0, 0x00c0, 0x0000
- };
- static short Default_GrayBits[] = {
- 0xaaaa, 0x5555, 0xaaaa, 0x5555,
- 0xaaaa, 0x5555, 0xaaaa, 0x5555,
- 0xaaaa, 0x5555, 0xaaaa, 0x5555,
- 0xaaaa, 0x5555, 0xaaaa, 0x5555,
- };
- static short Default_MaskBits[] = {
- 0x0003, 0x0007, 0x000f, 0x001f,
- 0x003f, 0x007f, 0x00ff, 0x01ff,
- 0x03ff, 0x07ff, 0x007f, 0x00f7,
- 0x00f3, 0x01e1, 0x01e0, 0x01c0
- };
- static char def_menu_font[] = "vtsingle";
-
- Pixmap Gray_Tile;
- Menu Menu_Default;
- Cursor Menu_DefaultCursor;
- char *Menu_DefaultFont;
- FontInfo *Menu_DefaultFontInfo;
-
- /*
- * AddMenuItem() adds a menu item to an existing menu, at the end of the
- * list, which are number sequentially from zero. The menuitem index is
- * return, or -1 if failed.
- */
-
- AddMenuItem(menu, text)
- register Menu *menu;
- register char *text;
- {
- register MenuItem *menuitem, **next;
- register int i;
- extern char *malloc();
-
- if(!menu || !text || (menuitem = (MenuItem *)malloc(sizeof(MenuItem)))
- == (MenuItem *)0)
- return(-1);
- bzero((char *)menuitem, sizeof(MenuItem));
- menuitem->itemText = text;
- menuitem->itemTextLength = strlen(text);
- for(i = 0, next = &menu->menuItems ; *next ; i++)
- next = &(*next)->nextItem;
- *next = menuitem;
- menu->menuFlags |= menuChanged;
- return(i);
- }
-
- /*
- * DisposeItem() releases the memory allocated for the given indexed
- * menuitem. Nonzero is returned if an item was actual disposed of.
- */
- DisposeItem(menu, i)
- register Menu *menu;
- register int i;
- {
- register MenuItem **next, **last, *menuitem;
-
- if(!menu || i < 0)
- return(0);
- next = &menu->menuItems;
- do {
- if(!*next)
- return(0);
- last = next;
- next = &(*next)->nextItem;
- } while(i-- > 0);
- menuitem = *last;
- *last = *next;
- free(menuitem);
- return(1);
- }
-
- /*
- * DisposeMenu() releases the memory allocated for the given menu.
- */
- DisposeMenu(menu)
- register Menu *menu;
- {
- static Unmap_Menu();
-
- if(!menu)
- return;
- if(menu->menuFlags & menuMapped)
- Unmap_Menu(menu);
- while(DisposeItem(menu, 0));
- if(menu->menuWindow)
- XDestroyWindow(menu->menuWindow);
- if(menu->menuSaved)
- XFreePixmap(menu->menuSaved);
- free(menu);
- }
-
- InitMenu(name)
- register char *name;
- {
- register char *cp;
- register Bitmap bit;
-
- /*
- * If the gray tile hasn't been set up, do it now.
- */
- if(!Gray_Tile) {
- if(!(bit = XStoreBitmap(grayWidth, grayHeight,
- Default_GrayBits)))
- return;
- Gray_Tile = XMakePixmap(bit, WhitePixel, BlackPixel);
- XFreeBitmap(bit);
- }
- Menu_Default.menuFlags = menuChanged;
- if((cp = XGetDefault(name, "MenuFreeze")) && strcmp(cp, "on") == 0)
- Menu_Default.menuFlags |= menuFreeze;
- if((cp = XGetDefault(name, "MenuSave")) && strcmp(cp, "on") == 0)
- Menu_Default.menuFlags |= menuSaveMenu;
- Menu_Default.menuInitialItem = -1;
- Menu_Default.menuBorderWidth = (cp = XGetDefault(name, "MenuBorder")) ?
- atoi(cp) : 2;
- Menu_Default.menuItemPad = (cp = XGetDefault(name, "MenuPad")) ?
- atoi(cp) : 3;
- Menu_DefaultFont = (cp = XGetDefault(name, "MenuFont")) ? cp :
- def_menu_font;
- };
-
- /*
- * ItemFlags returns the state of item "n" of the menu.
- */
- ItemFlags(menu, n)
- register Menu *menu;
- register int n;
- {
- register MenuItem *item;
-
- if(!menu || !menu->menuItems || n < 0)
- return(-1);
- for(item = menu->menuItems ; n > 0 ; n--)
- if(!(item = item->nextItem))
- return(0);
- return((item->itemFlags & itemSetMask) >> itemSetMaskShift);
- }
-
- /*
- * ItemText changes the text of item "n" of the menu.
- */
- ItemText(menu, n, text)
- register Menu *menu;
- register int n;
- char *text;
- {
- register MenuItem *item;
-
- if(!menu || !menu->menuItems || n < 0 || !text)
- return(0);
- for(item = menu->menuItems ; n > 0 ; n--)
- if(!(item = item->nextItem))
- return(0);
- item->itemText = text;
- menu->menuFlags |= menuChanged;
- return(1);
- }
-
- /*
- * NewMenu() returns a pointer to an initialized new Menu structure, or NULL
- * if failed.
- *
- * The Menu structure _menuDefault contains the default menu settings.
- */
- Menu *NewMenu(name, reverse)
- char *name;
- int reverse;
- {
- register Menu *menu;
- register int fg, bg;
- extern char *malloc();
-
- /*
- * If the GrayTile hasn't been defined, InitMenu() was never
- * run, so exit.
- */
- if(!Gray_Tile)
- return((Menu *)0);
- /*
- * Allocate the memory for the menu structure.
- */
- if((menu = (Menu *)malloc(sizeof(Menu))) == (Menu *)0)
- return((Menu *)0);
- /*
- * Initialize to default values.
- */
- *menu = Menu_Default;
- /*
- * If the menu font hasn't yet been gotten, go get it.
- */
- if(!menu->menuFontInfo) {
- if(!Menu_DefaultFontInfo && !(Menu_DefaultFontInfo =
- XOpenFont(Menu_DefaultFont)))
- return((Menu *)0);
- menu->menuFontInfo = Menu_DefaultFontInfo;
- }
- /*
- * If the menu cursor hasn't been given, make a default one.
- */
- if(!menu->menuCursor) {
- if(!Menu_DefaultCursor) {
- if(reverse) {
- fg = WhitePixel;
- bg = BlackPixel;
- } else {
- fg = BlackPixel;
- bg = WhitePixel;
- }
- if(!(Menu_DefaultCursor =
- XCreateCursor(defaultCursorWidth, defaultCursorHeight,
- Default_CursorBits, Default_MaskBits, defaultCursorX,
- defaultCursorY, fg, bg, GXcopy)))
- return((Menu *)0);
- }
- menu->menuCursor = Menu_DefaultCursor;
- }
- /*
- * Initialze the default background and border pixmaps and foreground
- * and background colors (black and white).
- */
- if(reverse) {
- menu->menuBgTile = BlackPixmap;
- menu->menuFgColor = WhitePixel;
- menu->menuBgColor = BlackPixel;
- } else {
- menu->menuBgTile = WhitePixmap;
- menu->menuFgColor = BlackPixel;
- menu->menuBgColor = WhitePixel;
- }
- /*
- * Set the menu title. If name is NULL or is an empty string, no
- * title will be displayed.
- */
- if(name && *name) {
- menu->menuTitleLength = strlen(menu->menuTitle = name);
- menu->menuTitleWidth = XStringWidth(name, menu->menuFontInfo,
- 0, 0);
- menu->menuItemTop = menu->menuFontInfo->height + 2 *
- menu->menuItemPad + 1;
- } else
- menu->menuTitleLength = menu->menuTitleWidth =
- menu->menuItemTop = 0;
- return(menu);
- }
-
- /*
- * SetItemCheck sets the check state of item "n" of the menu to "state".
- */
- SetItemCheck(menu, n, state)
- register Menu *menu;
- register int n;
- int state;
- {
- register MenuItem *item;
-
- if(!menu || !menu->menuItems || n < 0)
- return(0);
- for(item = menu->menuItems ; n > 0 ; n--)
- if(!(item = item->nextItem))
- return(0);
- if(state)
- item->itemFlags |= itemSetChecked;
- else
- item->itemFlags &= ~itemSetChecked;
- if(((item->itemFlags & itemSetMask) >> itemSetMaskShift) !=
- (item->itemFlags & itemStateMask)) {
- item->itemFlags |= itemChanged;
- menu->menuFlags |= menuItemChanged;
- } else
- item->itemFlags &= ~itemChanged;
- return(1);
- }
-
- /*
- * SetItemDisable sets the disable state of item "n" of the menu to "state".
- */
- SetItemDisable(menu, n, state)
- register Menu *menu;
- register int n;
- int state;
- {
- register MenuItem *item;
-
- if(!menu || !menu->menuItems || n < 0)
- return(0);
- for(item = menu->menuItems ; n > 0 ; n--)
- if(!(item = item->nextItem))
- return(0);
- if(state)
- item->itemFlags |= itemSetDisabled;
- else
- item->itemFlags &= ~itemSetDisabled;
- if(((item->itemFlags & itemSetMask) >> itemSetMaskShift) !=
- (item->itemFlags & itemStateMask)) {
- item->itemFlags |= itemChanged;
- menu->menuFlags |= menuItemChanged;
- } else
- item->itemFlags &= ~itemChanged;
- return(1);
- }
-
- /*
- * TrackMenu does most of the work of displaying the menu and tracking the
- * mouse.
- */
- TrackMenu(menu, event)
- register Menu *menu;
- register XButtonPressedEvent *event;
- {
- register MenuItem *item;
- register int i, button;
- register MenuItem *hilited_item = (MenuItem *)0;
- register int drawn;
- XButtonReleasedEvent ev;
- register int changed;
- int y, n, hilited_y, hilited_n, in_window;
- static MenuItem *Mouse_InItem(), *Y_InItem();
- static Unmap_Menu();
-
- /*
- * Check that things are reasonable.
- */
- if(!menu || !event || !menu->menuItems || event->type != ButtonPressed)
- return(-1);
- /*
- * Set the changed flag and clear the menu changed flags.
- */
- changed = menu->menuFlags & (menuChanged | menuItemChanged);
- /*
- * If the entire menu has changed, throw away any saved pixmap and
- * then call RecalcMenu().
- */
- if(changed & menuChanged) {
- if(menu->menuSaved)
- XFreePixmap(menu->menuSaved);
- menu->menuSaved = (Pixmap)0;
- if(!Recalc_Menu(menu))
- return(-1);
- changed &= ~menuItemChanged;
- }
- /*
- * Now if the window was never created, go ahead and make it. Otherwise
- * if the menu has changed, resize the window.
- */
- if(!menu->menuWindow) {
- if((menu->menuWindow = XCreateWindow(RootWindow, 0, 0,
- menu->menuWidth, menu->menuHeight, menu->menuBorderWidth,
- Gray_Tile, menu->menuBgTile)) == (Window)0)
- return(-1);
- XDefineCursor(menu->menuWindow, menu->menuCursor);
- XSelectInput(menu->menuWindow, ExposeWindow | EnterWindow |
- LeaveWindow | MouseMoved | ButtonReleased);
- } else if(changed & menuChanged)
- XChangeWindow(menu->menuWindow, menu->menuWidth,
- menu->menuHeight);
- /*
- * Figure out where the menu is supposed to go, from the initial button
- * press, and move the window there. Then map the menu.
- */
- if(!Move_Menu(menu, event) || !Map_Menu(menu))
- return(-1);
- /*
- * Try to grab the mouse, over a period of 10 seconds.
- */
- for(i = 10 ; ; ) {
- if(XGrabMouse(menu->menuWindow, menu->menuCursor,
- ButtonReleased | EnterWindow | LeaveWindow | MouseMoved))
- break;
- if(--i <= 0) {
- Unmap_Menu(menu);
- return(-1);
- }
- sleep(1);
- }
- /*
- * Save away the button that was pressed and use it to match a
- * corresponding ButtonReleased event.
- */
- button = event->detail & 03;
- /*
- * Now process events for the menu window.
- */
- drawn = 0;
- for( ; ; ) {
- XNextEvent(&ev);
- if(ev.type != ButtonReleased && ev.window != menu->menuWindow) {
- if(menu->menuEventHandler)
- (*menu->menuEventHandler)(&ev);
- continue;
- }
- switch(ev.type) {
- case ExposeWindow:
- /*
- * If we have a saved pixmap, display it. Otherwise
- * redraw the menu and save it away.
- */
- if(menu->menuSaved) {
- XPixmapPut(menu->menuWindow, 0, 0, 0, 0,
- menu->menuWidth, menu->menuHeight,
- menu->menuSaved, GXcopy, AllPlanes);
- /*
- * If the menuItemChanged flag is still set,
- * then we need to redraw certain menu items.
- * ("i" is the vertical position of the top
- * of the current item.)
- */
- if(changed & menuItemChanged) {
- i = menu->menuItemTop;
- for(item = menu->menuItems ; item ;
- item = item->nextItem) {
- if(item->itemFlags &
- itemChanged)
- Modify_Item(menu, item,
- i);
- i += item->itemHeight;
- }
- }
- } else
- Draw_Menu(menu);
- /*
- * If the menu has changed in any way and we want to
- * save the menu, throw away any existing save menu
- * image and make a new one.
- */
- XFlush();
- if(changed && (menu->menuFlags & menuSaveMenu)) {
- if(menu->menuSaved)
- XFreePixmap(menu->menuSaved);
- menu->menuSaved = XPixmapSave(menu->menuWindow,
- 0, 0, menu->menuWidth, menu->menuHeight);
- }
- /*
- * See which item the cursor may currently be in. If
- * it is in a non-disabled item, hilite it.
- */
- if(hilited_item = Mouse_InItem(menu, &hilited_y,
- &hilited_n, &in_window))
- XPixFill(menu->menuWindow, 0, hilited_y,
- menu->menuWidth, hilited_item->itemHeight,
- BlackPixmap, (Bitmap)0, GXinvert, InvertPlane);
- drawn++;
- break;
- case EnterWindow:
- in_window = TRUE;
- /* drop through */
- case MouseMoved:
- if(!drawn || !in_window)
- break;
- /*
- * See which item the cursor may currently be in. If
- * the item has changed, unhilite the old one and
- * then hilited the new one.
- */
- y = ((XEnterWindowEvent *)&ev)->y;
- if((item = Y_InItem(menu, &y, &n)) != hilited_item) {
- if(hilited_item)
- XPixFill(menu->menuWindow, 0,
- hilited_y, menu->menuWidth,
- hilited_item->itemHeight, BlackPixmap,
- (Bitmap)0, GXinvert, InvertPlane);
- if(hilited_item = item) {
- XPixFill(menu->menuWindow, 0,
- hilited_y = y, menu->menuWidth,
- item->itemHeight, BlackPixmap,
- (Bitmap)0, GXinvert, InvertPlane);
- hilited_n = n;
- }
- }
- break;
- case LeaveWindow:
- if(!drawn)
- break;
- /*
- * Unhilite any window that is currently hilited.
- */
- if(hilited_item) {
- XPixFill(menu->menuWindow, 0, hilited_y,
- menu->menuWidth, hilited_item->itemHeight,
- BlackPixmap, (Bitmap)0, GXinvert, InvertPlane);
- hilited_item = (MenuItem *)0;
- }
- in_window = FALSE;
- break;
- case ButtonReleased:
- /*
- * If the correct button was released, ungrab the mouse
- * and return the index number of any selected menu
- * item.
- */
- if((ev.detail & 0x3) == button) {
- if(in_window) {
- y = ((XButtonReleasedEvent *)&ev)->y;
- if((item = Y_InItem(menu, &y, &n)) !=
- hilited_item) {
- if(hilited_item)
- XPixFill(menu->menuWindow, 0,
- hilited_y, menu->menuWidth,
- hilited_item->itemHeight,
- BlackPixmap, (Bitmap)0,
- GXinvert, InvertPlane);
- if(hilited_item = item) {
- XPixFill(menu->menuWindow, 0,
- hilited_y = y, menu->menuWidth,
- hilited_item->itemHeight,
- BlackPixmap, (Bitmap)0,
- GXinvert, InvertPlane);
- hilited_n = n;
- }
- }
- }
- XUngrabMouse();
- menu->menuFlags &= ~(menuChanged |
- menuItemChanged);
- Unmap_Menu(menu);
- XFlush();
- if(hilited_item)
- return(menu->menuInitialItem =
- hilited_n);
- return(-1);
- }
- break;
- }
- }
- }
-
- /*
- * Recalculate all of the various menu and item variables.
- */
- static Recalc_Menu(menu)
- register Menu *menu;
- {
- register MenuItem *item;
- register int max, i, height, fontheight;
-
- /*
- * We must have already gotten the menu font.
- */
- if(!menu->menuFontInfo)
- return(0);
- /*
- * Initialize the various max width variables.
- */
- fontheight = menu->menuFontInfo->height;
- height = menu->menuItemTop;
- menu->menuMaxTextWidth = menu->menuTitleWidth;
- /*
- * The item height is the maximum of the font height and the
- * checkbox height.
- */
- max = fontheight;
- if(checkMarkHeight > max)
- max = checkMarkHeight;
- /*
- * Go through the menu item list.
- */
- for(item = menu->menuItems ; item ; item = item->nextItem) {
- /*
- * If the item text is a single dash, we assume this is
- * a line separator and treat it special.
- */
- if(strcmp(item->itemText, "-") == 0)
- height += (item->itemHeight = lineSeparatorHeight);
- else {
- height += (item->itemHeight = max);
- /*
- * Check the text width with the max value stored in
- * menu.
- */
- if((item->itemTextWidth = XStringWidth(item->itemText,
- menu->menuFontInfo, 0, 0)) > menu->menuMaxTextWidth)
- menu->menuMaxTextWidth = item->itemTextWidth;
- }
- /*
- * If the itemChanged flag is set, set the state bits.
- */
- if(item->itemFlags & itemChanged) {
- item->itemFlags = (item->itemFlags & ~itemStateMask) |
- ((item->itemFlags & itemSetMask) >> itemSetMaskShift);
- item->itemFlags &= ~itemChanged;
- }
- }
- /*
- * Set the menu height and then set the menu width.
- */
- menu->menuHeight = height;
- menu->menuWidth = 3 * menu->menuItemPad + menu->menuMaxTextWidth +
- checkMarkWidth;
- return(1);
- }
-
- /*
- * Figure out where to popup the menu, relative to the where the button was
- * pressed.
- */
- static Move_Menu(menu, ev)
- register Menu *menu;
- XButtonPressedEvent *ev;
- {
- register MenuItem *item;
- register int n, x, y;
- int ev_x, ev_y;
- int total_width;
- Window subw;
-
- /*
- * Get the coordinates of the mouse when the button was pressed.
- */
- XInterpretLocator(RootWindow, &ev_x, &ev_y, &subw, ev->location);
- /*
- * Try to popup the menu so that the cursor is centered within the
- * width of the menu, but compensate if that would run it outside
- * the display area.
- */
- total_width = menu->menuWidth + 2 * menu->menuBorderWidth;
- if((x = ev_x - total_width / 2) < 0)
- x = 0;
- else if(x + total_width > DisplayWidth())
- x = DisplayWidth() - total_width;
- #ifdef DROPMENUS
- y = 0;
- #else DROPMENUS
- /*
- * If we have an inital item, try to popup the menu centered
- * vertically within this item.
- */
- if(menu->menuInitialItem >= 0) {
- /*
- * Look through the item list. "y" is the vertical position
- * of the top of the current item and "n" is the item number.
- */
- y = menu->menuItemTop + menu->menuBorderWidth;
- for(n = 0, item = menu->menuItems ; ; n++) {
- /*
- * On finding the intial item, center within this item.
- */
- if(n == menu->menuInitialItem) {
- y += item->itemHeight / 2;
- break;
- }
- y += item->itemHeight;
- /*
- * If we run out of items, turn off the initial item
- * and treat this as if no initial item.
- */
- if(!(item = item->nextItem)) {
- menu->menuInitialItem = -1;
- goto noInitial;
- }
- }
- /*
- * If no initial item, try to popup the menu centered in the item
- * nearest the center of the menu.
- */
- } else {
- noInitial:
- /*
- * Look through the item list. "y" is the vertical position
- * of the top of the current item and "n" is the vertical
- * position of the center of the menu.
- */
- y = menu->menuItemTop + menu->menuBorderWidth;
- for(n = menu->menuHeight / 2, item = menu->menuItems ; item ;
- item = item->nextItem)
- /*
- * If the center of the menu is in this item, we
- * center within this item.
- */
- if((y += item->itemHeight) > n) {
- y -= item->itemHeight / 2;
- break;
- }
- }
- #endif DROPMENU
- /*
- * If the menu extends above outside of the display, warp
- * the mouse vertically so the menu will all show up.
- */
- if((y = ev_y - y) < 0) {
- XWarpMouse(RootWindow, ev_x, ev_y - y);
- y = 0;
- } else if((n = y + menu->menuHeight + 2 * menu->menuBorderWidth
- - DisplayHeight()) > 0) {
- XWarpMouse(RootWindow, ev_x, ev_y - n);
- y -= n;
- }
- XMoveWindow(menu->menuWindow, x, y);
- /*
- * If we are in freeze mode, save what will be the coordinates of
- * the save image.
- */
- if(menu->menuFlags & menuFreeze) {
- menu->menuSavedImageX = x;
- menu->menuSavedImageY = y;
- }
- return(1);
- }
-
- /*
- * Map the menu window.
- */
- static Map_Menu(menu)
- register Menu *menu;
- {
- register int i;
-
- /*
- * If we are in freeze mode, save the pixmap underneath where the menu
- * will be (including the border).
- */
- if(menu->menuFlags & menuFreeze) {
- XGrabServer();
- i = 2 * menu->menuBorderWidth;
- if((menu->menuSavedImage = XPixmapSave(RootWindow,
- menu->menuSavedImageX, menu->menuSavedImageY, menu->menuWidth
- + i, menu->menuHeight + i)) == (Pixmap)0)
- return(0);
- }
- /*
- * Actually map the window.
- */
- XMapWindow(menu->menuWindow);
- menu->menuFlags |= menuMapped;
- return(1);
- }
-
- /*
- * Draw the entire menu in the blank window.
- */
- static Draw_Menu(menu)
- register Menu *menu;
- {
- register MenuItem *item;
- register int top = menu->menuItemTop;
- register int x = menu->menuItemPad;
- register int y, dim;
-
- /*
- * If we have a menu title, draw it first, centered and hilited.
- */
- if(menu->menuTitleLength) {
- XPixSet(menu->menuWindow, 0, 0, menu->menuWidth,
- top - 1, menu->menuFgColor);
- XText(menu->menuWindow, (menu->menuWidth -
- menu->menuTitleWidth) / 2, menu->menuItemPad, menu->menuTitle,
- menu->menuTitleLength, menu->menuFontInfo->id,
- menu->menuBgColor, menu->menuFgColor);
- }
- /*
- * For each item in the list, first draw any check mark and then
- * draw the rest of it.
- */
- for(item = menu->menuItems ; item ; item = item->nextItem) {
- SetStateFlags(item);
- dim = (item->itemFlags & itemDisabled);
- /*
- * Draw the check mark, possibly dimmed, wherever is necessary.
- */
- if(item->itemFlags & itemChecked) {
- XBitmapBitsPut(menu->menuWindow, x, y = top +
- (item->itemHeight - checkMarkHeight) / 2,
- checkMarkWidth, checkMarkHeight, dim ? Check_GrayBits :
- Check_MarkBits, menu->menuFgColor, menu->menuBgColor,
- (Bitmap)0, GXcopy, AllPlanes);
- }
- /*
- * Draw the item, possibly dimmed.
- */
- Draw_Item(menu, item, top, dim);
- top += item->itemHeight;
- }
- }
-
- /*
- * Modify the item at vertical position y. This routine is table driven and
- * the state and set bits are each 2 bits long, contiguous, the least
- * significant bits in the flag word and with the state bits in bits 0 & 1.
- */
-
- #define drawCheck 0x10
- #define removeCheck 0x08
- #define dimCheck 0x04
- #define drawItem 0x02
- #define dimItem 0x01
-
- static char Modify_Table[] = {
- 0x00, 0x02, 0x08, 0x0a, 0x01, 0x00, 0x09, 0x08,
- 0x10, 0x12, 0x00, 0x12, 0x15, 0x14, 0x05, 0x00
- };
-
- static Modify_Item(menu, item, top)
- register Menu *menu;
- register MenuItem *item;
- int top;
- {
- register int x = menu->menuItemPad;
- register int y;
- register int center = top + item->itemHeight / 2;
- register int func = Modify_Table[item->itemFlags &
- (itemStateMask | itemSetMask)];
-
- /*
- * If we really won't be making a change, return.
- */
- if(func == 0)
- return;
- /*
- * Draw the check mark if needed, possibly dimmed.
- */
- y = center - (checkMarkHeight / 2);
- if(func & (drawCheck | dimCheck))
- XBitmapBitsPut(menu->menuWindow, x, y, checkMarkWidth,
- checkMarkHeight, (func & dimCheck) ? Check_GrayBits :
- Check_MarkBits, menu->menuFgColor, menu->menuBgColor,
- (Bitmap)0, GXcopy, AllPlanes);
- /*
- * Remove the check mark if needed.
- */
- if(func & removeCheck)
- XTileSet(menu->menuWindow, x, y, checkMarkWidth,
- checkMarkHeight, menu->menuBgTile);
- /*
- * Call Draw_Item if we need to draw or dim the item.
- */
- if((x = func & dimItem) || (func & drawItem))
- Draw_Item(menu, item, top, x);
- /*
- * Update state flags.
- */
- SetStateFlags(item);
- }
-
- /*
- * Draw the item (less check mark) at vertical position y.
- * Dim the item if "dim" is set.
- */
- static Draw_Item(menu, item, y, dim)
- register Menu *menu;
- register MenuItem *item;
- register int y;
- int dim;
- {
- register int x = 2 * menu->menuItemPad + checkMarkWidth;
- register int center = y + item->itemHeight / 2;
-
- /*
- * If the item text is a single dash, draw a separating line.
- */
- if(strcmp(item->itemText, "-") == 0) {
- XLine(menu->menuWindow, 0, center, menu->menuWidth, center,
- 1, 1, menu->menuFgColor, GXcopy, AllPlanes);
- return;
- }
- /*
- * Draw and/or dim the text, centered vertically.
- */
- y = center - (menu->menuFontInfo->height / 2);
- if(dim) {
- XTileSet(menu->menuWindow, x, y, item->itemTextWidth,
- menu->menuFontInfo->height, Gray_Tile);
- XTextPad(menu->menuWindow, x, y, item->itemText,
- item->itemTextLength, menu->menuFontInfo->id, 0, 0,
- menu->menuFgColor, menu->menuBgColor, menu->menuFgColor ?
- GXand : GXor, AllPlanes);
- } else
- XText(menu->menuWindow, x, y, item->itemText,
- item->itemTextLength, menu->menuFontInfo->id,
- menu->menuFgColor, menu->menuBgColor);
- }
-
- /*
- * Determine which enabled menu item the mouse is currently in. Return the
- * top position of this item and its item number. Set inwindow to whether
- * we are or not.
- */
- static MenuItem *Mouse_InItem(menu, top, n, inwindow)
- register Menu *menu;
- int *top, *n, *inwindow;
- {
- int x, y;
- Window subw;
- static MenuItem *Y_InItem();
-
- /*
- * Find out where the mouse is. If its not in the menu window,
- * return NULL.
- */
- XQueryMouse(RootWindow, &x, &y, &subw);
- if(subw != menu->menuWindow) {
- *inwindow = FALSE;
- return((MenuItem *)0);
- }
- *inwindow = TRUE;
- /*
- * Now get the coordinates relative to the menu window.
- */
- XInterpretLocator(menu->menuWindow, &x, &y, &subw, (x << 16) | y);
- /*
- * Call Y_InItem().
- */
- *top = y;
- return(Y_InItem(menu, top, n));
- }
-
- /*
- * Return which enabled item the locator is in. Also return the
- * top position of this item and its item number. Initial y passed
- * in top.
- */
- static MenuItem *Y_InItem(menu, top, n)
- register Menu *menu;
- int *top, *n;
- {
- register MenuItem *item;
- register int t, i;
- register int y = *top;
- Window subw;
-
- /*
- * Go through the item list. "t" is the vertical position of the
- * current item and "i" is its item number.
- */
- t = menu->menuItemTop;
- /*
- * If the mouse is before the first item, return.
- */
- if(y < t)
- return((MenuItem *)0);
- for(i = 0, item = menu->menuItems ; item ; i++, item = item->nextItem) {
- /*
- * If the y coordinate is within this menu item, then return.
- * But don't return disable items.
- */
- if(t + item->itemHeight > y) {
- if(item->itemFlags & itemDisabled)
- return((MenuItem *)0);
- *top = t;
- *n = i;
- return(item);
- }
- t += item->itemHeight;
- }
- /*
- * Should never get here.
- */
- return((MenuItem *)0);
- }
-
- /*
- * Unmap_Menu() unmaps a menu, if it is currently mapped.
- */
- static Unmap_Menu(menu)
- register Menu *menu;
- {
- register int i;
-
- if(!menu || !(menu->menuFlags & menuMapped))
- return;
- if(menu->menuFlags & menuFreeze) {
- XUnmapTransparent(menu->menuWindow);
- i = 2 * menu->menuBorderWidth;
- XPixmapPut(RootWindow, 0, 0, menu->menuSavedImageX,
- menu->menuSavedImageY, menu->menuWidth + i,
- menu->menuHeight + i, menu->menuSavedImage,
- GXcopy, AllPlanes);
- XFreePixmap(menu->menuSavedImage);
- XUngrabServer();
- } else
- XUnmapWindow(menu->menuWindow);
- menu->menuFlags &= ~menuMapped;
- }
- #endif MODEMENU
- RAZZLE!DAZZLE
- fi # End menu.c
- echo '***** End of' xterm 6.6B - Part 5 of 7 '*****'
- exit
-